<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>77_封装</title>
		<script>
			/* 
			
			面向对象的特点:
				封装、继承和多态
			
			1.封装
				- 对象就是一个用来存储不同属性的容器
				-对象不仅负责属性，还要负责数据的安全
				-直接添加到对象中的属性，并不安全，因为它们可以被任意的修改
				-如何确保数据的安全:
					-1.私有化数据
						将需要保护的数据设置为私有，只能在类内部使用;
					2.提供setter和getter方法来开放对数据的操作
						-属性设置私有，通过getter setter方法操作属性带来的好处
						1.可以控制属性的读写权限
						2.可以在方法中对属性的值进行验证
			
			2.封装主要用来保证数据的安全
				- 实现封装的方式:
				1.属性私有化加#
				2.通过getter和setter方法来操作属性
					get 属性名( ){
						return this.#属性
					}
					set 属性名(参数){
						this.#属性=参数
					}
			 */
			class Person {
				#address = "花果山" // 实例使用#开头就变成了私有属性，私有属性只能在类内部访问
				#name;
				#age;
				#gender;
				constructor(name, age, gender, address) {
					this.#name = name;
					this.#age = age;
					this.#gender = gender;
					//私有属性必须先在上面声明，否则报错。
					this.#address = address;
				}

				// setter方法，用来设置属性
				setName(name) {
					this.#name = name
				}
				//
				getName() {
					return this.#name
				}
				
				/* 
					1.每次修改或访问name都set，get方法，比较麻烦。
					2.这样写每次就可以p1.age=11来访问和修改它的私有属性了。
				 */

				get age() {
					return this.#age;
				}

				set age(age) {
					this.#age = age;
				}

				sayHello() {
					console.log(this.name, this.#address);
				}
			}

			const p1 = new Person("孙悟空", 11, "男", "花果山噗噗..")
			p1.setName("猪八戒")
			p1.age=101;
			console.log(p1);
		</script>
	</head>
	<body>
	</body>
</html>